#include "XmlParser.h"

#include <iostream>

#include <QDomDocument>
#include <QtXml>
#include <QDomNode>
#include <QDomElement>
#include <QFile>

#include "BBClass.h"
#include "Util.h"

#include "Validator.h"

XmlParser* XmlParser::m_instance = NULL;

XmlParser* XmlParser::instance()
{
	//Check if is the first time using
	if ( m_instance == NULL )
	{
		m_instance = new XmlParser();
	}

	return m_instance;
}

QList<BBClass>* XmlParser::getUserClasses( QString xmlFilePath )
{
	QFile file( xmlFilePath );

	//Check if file opened
	if( !file.open( QFile::ReadOnly ) )
	{
		//TODO: Erro Message - Arquivo nao foi aberto
		file.close();
	}

	QDomDocument doc;

	//TODO: Verificar se essa parte do codigo é necessaria. Pelo jeito, ele nao é necessario
	//Check the encoding of the document
	if( !doc.setContent( &file ) )
	{
		//TODO: Erro Message - Arquivo com formato diferente de XML
		file.close();
	}

	Validator* validator = Validator::instance();
	QString errorMessage = validator->check( doc );

	//Check if occurred any error in xml file mapping
	if ( errorMessage != "" )
	{
		std::cout << errorMessage.toStdString();
	}
 
	QDomNode node = doc.firstChild();
	QDomElement element;

	//Check all nodes
	while( !node.isNull() )
	{
		element = node.toElement();

		//Check if current node is the BlackBear mapping node
		if( element.tagName() == XML_MAPPING_NODE_BLACKBEAR )
		{
			break;
		}
		node = node.nextSibling();
	}

	//Check if the BlackBear mapping node was not found
	if( node.isNull() )
	{
		//TODO: Erro Message - No Blackbear-mapping nao encontrado 
		file.close();
	}

	BBClass * classCurrent;
	QList<BBClass>* classes = new QList<BBClass>();

	//Get first specified class
	node = node.firstChild();

	//Get all class nodes
	while( !node.isNull() )
	{
		element = node.toElement();

		//Check if node defines a class
		if( element.tagName() == XML_MAPPING_CLASS )
		{
			//tableCurrent = new BBTable( element.attribute( XML_MAPPING_ATTRIBUTE_NAME ) );
			classCurrent = new BBClass();
			classCurrent->setName( element.attribute( XML_MAPPING_ATTRIBUTE_NAME ) );

			//Check if class has a superclass
			if ( element.hasAttribute( XML_MAPPING_ATTRIBUTE_EXTENDS ) )
			{
				classCurrent->setExtension( element.attribute( XML_MAPPING_ATTRIBUTE_EXTENDS ) );
			}

			//TODO: Verificar se é necessario etstar sempre o tag dos nodes para verificar se o usuario preencheu corretamente o xml
			//if( element.tagName() != "class" )
			//{
			//TODO: Erro message: Node com nome diferente de 'class'
			//}

			//Get first class
			QDomNode nodeAttribute = node.firstChild();

			//Get all attributes nodes
			while( !nodeAttribute.isNull() )
			{
				QDomElement elementAttribute = nodeAttribute.toElement();

				//Check if node defines a attribute
				if( elementAttribute.tagName() == XML_MAPPING_ATTRIBUTE )
				{
					//TODO: Verificar se é necessario etstar sempre o tag dos nodes para verificar se o usuario preencheu corretamente o xml
					//if( element.tagName() != "attribute" )
					//{
					//TODO: Erro message: Node com nome diferente de 'attribute'
					//}
					//
					//Get atribute's name and type

					classCurrent->setAttributeType( elementAttribute.attribute( XML_MAPPING_ATTRIBUTE_NAME ),
													elementAttribute.attribute( XML_MAPPING_ATTRIBUTE_TYPE ) );
				}
				//Get next attribute
				nodeAttribute = nodeAttribute.nextSibling();
			}

			classes->append( *classCurrent );
		}
		//Get next class
		node = node.nextSibling();
	}

	return classes;
}
